package com.hm.PushCaseService.framework.service.token;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.hm.PushCaseService.framework.pojo.TokenBean;
import com.hm.PushCaseService.framework.service.crypto.ICryptoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.HashMap;


@Service
public class TokenService implements ITokenService {

    private static final Logger logger = LoggerFactory.getLogger(TokenService.class);

    //默认有效期是8小时(单位：秒)
    private static final long SURVIVAL_TIME = 60 * 60 * 8;

    //Token加解密-秘钥(32位)
    private static final String TokenSecretKey = "T11TlHk7D3Phq7*9hXDilvL7D3PJ85P7";

    private final ICryptoService iCryptoService;

    @Qualifier("jedisPool")
    private final JedisPool jedisPool;

    public TokenService(JedisPool jedisPool, ICryptoService iCryptoService) {
        this.iCryptoService = iCryptoService;
        this.jedisPool = jedisPool;
    }

    @Override
    public String saveToken(String userId) {
        try (Jedis jedis = jedisPool.getResource()) {
            //根据userId生成token
            TokenBean bean = new TokenBean();
            bean.userId = userId;
            bean.creationTime = System.currentTimeMillis();
            String str = JSON.toJSONString(bean);
            String token = iCryptoService.encrypt(TokenSecretKey, str);
            //userId和token对应
            jedis.setex(userId, SURVIVAL_TIME, token);
            return token;
        } catch (Exception e) {
            logger.error("保存token失败：" + e);
        }
        return "";
    }

    @Override
    public HashMap<String, String> verifier(String token) {
        //校验token
        HashMap<String, String> resMap = new HashMap<>();
        try (Jedis jedis = jedisPool.getResource()) {
            String realToken = iCryptoService.decrypt(TokenSecretKey, token);
            TokenBean tokenBean = JSONObject.parseObject(realToken, TokenBean.class);
            String userId = tokenBean.userId;
            //通过userId拿到redis中的token->key:userID,value:token
            boolean exists = jedis.exists(userId);
            if (!exists) {
                //不存在，说明过期了
                resMap.put("state", "001");
                resMap.put("msg", "Token已过期,请重新登录");
                return resMap;
            }
            //判断redis中的token和参数token是否相等
            String latestToken = jedis.get(userId);
            if (latestToken == null || !latestToken.equals(token)) {
                //被其他设备登录了，不是最新的token
                resMap.put("state", "002");
                resMap.put("msg", "已在其他设备登陆，请从新登录");
                return resMap;
            }
            //校验通过
            resMap.put("userId", userId);
            resMap.put("state", "000");
            resMap.put("msg", "验证通过");
        } catch (Exception e) {
            resMap.put("state", "003");
            resMap.put("msg", "token验证异常：" + e.getMessage());
        }
        return resMap;
    }

}
